home *** CD-ROM | disk | FTP | other *** search
- /* kernel.c -- interface to kernel structures/ioctls */
-
- /*
- * srouted -- silent routing daemon
- * Copyright (C) 1995 Kevin Buhr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #ifndef lint
- static char rcsid[] = "$Id: kernel.c,v 1.4 1995/02/20 17:44:16 buhr Exp $";
- #endif /* not lint */
-
- #include "defs.h"
- #include "table.h"
- #include "kernel.h"
-
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <net/if.h>
- #include <stdio.h>
-
-
- static int s; /* socket for route IOCTLs */
-
- /*
- * Get configuration of directly connected interfaces
- */
-
- void kr_getifconf(void)
- {
- struct ifconf ifc;
- struct ifreq *ife,ifr;
- struct tb_iface *iface;
- int ifi;
- short ifflags;
-
- if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- warn1(ERCKR_NOIPSOCK,errno);
- goto getif_failed;
- }
- ifc.ifc_len=sizeof(page);
- ifc.ifc_buf=page;
-
- /* get configuration of the interfaces */
- if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
- warn2(ERCKR_IOCTL,SIOCGIFCONF,errno);
- goto getif_failed;
- }
-
- /* step through interfaces */
- for(ife=ifc.ifc_req; (char *) ife < (char *) ifc.ifc_req
- +ifc.ifc_len; ife++) {
-
- if(!ife->ifr_name[0])
- continue;
-
- ifi=tb_newiface();
- if(ifi==-1) {
- die0(ERCKR_IFFULL);
- }
-
- iface=&tb_iface[ifi];
- memcpy(iface->tbif_dev,ife->ifr_name,IFNAMSIZ);
- iface->tbif_myaddr=ife->ifr_addr;
-
- memcpy(ifr.ifr_name,iface->tbif_dev,IFNAMSIZ);
-
- #define IFIOCTL(s,num,arg) \
- if(ioctl((s),(num),(arg)) < 0) { \
- warn2(ERCKR_IOCTL,(num),errno); \
- continue; \
- }
-
- IFIOCTL(s, SIOCGIFFLAGS, (char *)&ifr);
- ifflags=ifr.ifr_flags;
- if((ifflags&IFF_UP)==0) {
- continue;
- }
- if(ifflags&IFF_LOOPBACK) {
- iface->tbif_flags|=TBIFF_LOOPBACK;
- }
- if(ifflags&IFF_POINTOPOINT) {
- iface->tbif_flags|=TBIFF_POINTOPOINT;
- IFIOCTL(s, SIOCGIFDSTADDR, (char *)&ifr);
- iface->tbif_dstaddr=ifr.ifr_dstaddr;
- }
- if(ifflags&IFF_BROADCAST) {
- iface->tbif_flags|=TBIFF_BROADCAST;
- IFIOCTL(s, SIOCGIFBRDADDR, (char *)&ifr);
- iface->tbif_broadaddr=ifr.ifr_broadaddr;
- }
- IFIOCTL(s, SIOCGIFNETMASK, (char *)&ifr);
- iface->tbif_netmask=ifr.ifr_netmask;
- IFIOCTL(s, SIOCGIFMETRIC, (char *)&ifr);
- iface->tbif_metric=ifr.ifr_metric+1;
- if(iface->tbif_metric<1 || iface->tbif_metric >= TBM_INFINITY)
- iface->tbif_metric=1; /* bad metric, so make one up */
- iface->tbif_flags|=TBIFF_USED|TBIFF_UP;
- }
-
- getif_failed:
- ;
-
- }
-
-
- /*
- * Delete a route from the kernel tables
- */
-
- void kr_delroute( int route )
- {
- struct rtentry kr;
-
- kr.rt_dst = tb_route[route].tbrt_dst;
- kr.rt_dev = NULL;
-
- if( ioctl( s, SIOCDELRT, (char *) &kr ) < 0 ) {
- warn1(ERCKR_XDELRT, errno);
- }
- note1( ERCKR_DELRT, route );
- }
-
-
- /*
- * Add a route to the kernel tables
- */
-
- void kr_addroute( int route )
- {
- struct rtentry kr;
- struct tb_route *rtp;
-
- rtp = &tb_route[route];
- kr.rt_dst = rtp->tbrt_dst;
- kr.rt_gateway = rtp->tbrt_gateway;
- kr.rt_genmask = rtp->tbrt_mask;
- kr.rt_metric = rtp->tbrt_metric;
- kr.rt_flags = RTF_UP;
- if( rtp->tbrt_flags & TBRTF_DIRECT ) {
- if( rtp->tbrt_iface != -1 )
- kr.rt_dev = tb_iface[rtp->tbrt_iface].tbif_dev;
- } else {
- kr.rt_dev = NULL;
- kr.rt_flags |= RTF_GATEWAY;
- }
- if( rtp->tbrt_flags & TBRTF_HOST )
- kr.rt_flags |= RTF_HOST;
-
- if( ioctl( s, SIOCADDRT, (char *) &kr ) < 0 ) {
- warn1(ERCKR_XADDRT, errno);
- }
- note1( ERCKR_ADDRT, route );
- }
-